package com.han.core.job;

import com.doudian.open.core.AccessToken;
import com.doudian.open.core.AccessTokenBuilder;
import com.han.common.constant.CacheConstants;
import com.han.core.redis.RedisCache;
import com.han.service.ShopService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
@EnableScheduling
public class TokenScheduleJob {

    @Resource
    ShopService shopService;
    @Resource
    RedisCache redisCache;

    private static final String lockStr = "lock_refresh_token";

    /**
     * 定时刷新所有access_token
     */
    @Scheduled(cron = "${refresh.token.cron:0 0/1 * 1/1 * ? }")
    public void refreshTokenJob() {
        //1.加锁，有一个执行就好，
        //目前没有维护Type枚举，直接传入字符串
        if (!redisCache.setIfAbsent(lockStr, "", 1, TimeUnit.MINUTES)) {
            //抢占失败；
            log.info("刷新token-job抢占锁失败");
            return;
        }
        /**
         * 获取token失败，报错：生成token失败, grant_type参数取值不正确,请参照文档根据应用类型填写不同的值“，
         * 一般是由于：传入的 grant_type参数取值不正确，即授权类型不正确导致的。
         * 需要开发者自查创建的应用是工具型还是自用型应用。根据不同的应用，请求参数的 grant_type需要传入不同值。
         * 且若是工具型应用，需要传code参数。
         */
        Collection<String> collection = redisCache.keys(CacheConstants.REFRESH_TOKEN_PREFIX + "**");
        log.info("获取所有keys 集合：{}", collection);
        collection.forEach(x->{
            //获取所有缓存中的Refresh_key,单独刷新
            //刷新redis中refresh_token的过期时间
            //刷新redis中access_token的过期时间
            AccessToken refresh = AccessTokenBuilder.refresh(StringUtils.replace(x,CacheConstants.REFRESH_TOKEN_PREFIX,""));
            if(Objects.equals(refresh.getCode(), "10000")){
                boolean refreshExpire = redisCache.expire(CacheConstants.REFRESH_TOKEN_PREFIX+refresh.getRefreshToken(), CacheConstants.REFRESH_TOKEN_EXPIRE, TimeUnit.MINUTES);
                boolean tokenExpire =redisCache.expire(CacheConstants.TOKEN_PREFIX+refresh.getAccessToken(),CacheConstants.TOKEN_EXPIRE,TimeUnit.MINUTES);
                log.info("刷新店铺access_token:[ID:{},Name:{}]，accessToken,更新redis,refresh:[{}],access_token[{}]",
                        refresh.getShopName(), refresh.getShopId(), refreshExpire, tokenExpire);
            }else {
                log.warn("调用AccessTokenBuilder.refresh刷新Token失败:refreshToKen[{}]",x);
            }

        });

    }

}
